// Copyright (c) 2024 CHANGLEI. All rights reserved.

import 'package:charts_grasp/src/circular_chart/renderer/circular_series.dart';
import 'package:charts_grasp/src/circular_chart/renderer/renderer_base.dart';
import 'package:charts_grasp/src/circular_chart/renderer/renderer_extension.dart';
import 'package:charts_grasp/src/common/utils/typedef.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

class RadialBarSeries<T, D> extends CircularSeries<T, D> {
  RadialBarSeries({
    super.key,
    super.onCreateRenderer,
    super.onRendererCreated,
    super.onPointTap,
    super.onPointDoubleTap,
    super.onPointLongPress,
    super.dataSource,
    required ChartValueMapper<T, D> xValueMapper,
    required ChartValueMapper<T, num> yValueMapper,
    ChartValueMapper<T, Color>? pointColorMapper,
    ChartShaderMapper<T>? pointShaderMapper,
    ChartValueMapper<T, String>? pointRadiusMapper,
    ChartValueMapper<T, String>? dataLabelMapper,
    ChartValueMapper<T, String>? sortFieldValueMapper,
    this.trackColor = const Color.fromRGBO(234, 236, 239, 1),
    this.trackBorderWidth = 0.0,
    this.trackOpacity = 1,
    this.useSeriesColor = false,
    this.trackBorderColor = Colors.transparent,
    this.maximumValue,
    super.dataLabelSettings,
    super.radius,
    super.innerRadius,
    super.gap,
    double? strokeWidth,
    super.opacity,
    Color? strokeColor,
    super.enableTooltip,
    super.name,
    super.animationDuration,
    super.animationDelay,
    super.selectionBehavior,
    super.sortingOrder,
    super.legendIconType,
    super.cornerStyle,
    super.initialSelectedDataIndexes,
  }) : super(
          xValueMapper: (index) => xValueMapper(dataSource![index], index),
          yValueMapper: (index) => yValueMapper(dataSource![index], index),
          pointColorMapper: (index) =>
              pointColorMapper != null ? pointColorMapper(dataSource![index], index) : null,
          pointRadiusMapper: (index) =>
              pointRadiusMapper != null ? pointRadiusMapper(dataSource![index], index) : null,
          pointShaderMapper: pointShaderMapper != null
              ? (dynamic data, index, color, rect) =>
                  pointShaderMapper(dataSource![index], index, color, rect)
              : null,
          dataLabelMapper: (index) => dataLabelMapper != null ? dataLabelMapper(dataSource![index], index) : null,
          sortFieldValueMapper:
              sortFieldValueMapper != null ? (index) => sortFieldValueMapper(dataSource![index], index) : null,
          borderColor: strokeColor,
          borderWidth: strokeWidth,
        );

  final Color trackColor;

  final double? maximumValue;

  final Color trackBorderColor;

  final double trackBorderWidth;

  final double trackOpacity;

  final bool useSeriesColor;

  RadialBarSeriesRenderer createRenderer(CircularSeries<T, D> series) {
    RadialBarSeriesRenderer seriesRenderer;
    if (onCreateRenderer != null) {
      seriesRenderer = onCreateRenderer!(series) as RadialBarSeriesRenderer;
      return seriesRenderer;
    }
    return RadialBarSeriesRendererExtension();
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) {
      return true;
    }
    if (other.runtimeType != runtimeType) {
      return false;
    }

    return other is RadialBarSeries &&
        other.animationDuration == animationDuration &&
        other.animationDelay == animationDelay &&
        other.borderColor == borderColor &&
        other.borderWidth == borderWidth &&
        other.cornerStyle == cornerStyle &&
        other.dataLabelMapper == dataLabelMapper &&
        other.dataLabelSettings == dataLabelSettings &&
        other.dataSource == dataSource &&
        other.enableTooltip == enableTooltip &&
        other.gap == gap &&
        listEquals(other.initialSelectedDataIndexes, initialSelectedDataIndexes) &&
        other.innerRadius == innerRadius &&
        other.legendIconType == legendIconType &&
        other.maximumValue == maximumValue &&
        other.name == name &&
        other.onCreateRenderer == onCreateRenderer &&
        other.onRendererCreated == onRendererCreated &&
        other.onPointTap == onPointTap &&
        other.onPointDoubleTap == onPointDoubleTap &&
        other.onPointLongPress == onPointLongPress &&
        other.opacity == opacity &&
        other.pointColorMapper == pointColorMapper &&
        other.pointRadiusMapper == pointRadiusMapper &&
        other.pointShaderMapper == pointShaderMapper &&
        other.radius == radius &&
        other.selectionBehavior == selectionBehavior &&
        other.sortFieldValueMapper == sortFieldValueMapper &&
        other.sortingOrder == sortingOrder &&
        other.trackBorderColor == trackBorderColor &&
        other.trackBorderWidth == trackBorderWidth &&
        other.trackColor == trackColor &&
        other.trackOpacity == trackOpacity &&
        other.useSeriesColor == useSeriesColor &&
        other.xValueMapper == xValueMapper &&
        other.yValueMapper == yValueMapper;
  }

  @override
  int get hashCode {
    final List<Object?> values = <Object?>[
      animationDuration,
      animationDelay,
      borderColor,
      borderWidth,
      cornerStyle,
      dataLabelMapper,
      dataLabelSettings,
      dataSource,
      enableTooltip,
      gap,
      initialSelectedDataIndexes,
      innerRadius,
      legendIconType,
      maximumValue,
      name,
      onCreateRenderer,
      onRendererCreated,
      onPointTap,
      onPointDoubleTap,
      onPointLongPress,
      opacity,
      pointColorMapper,
      pointRadiusMapper,
      pointShaderMapper,
      radius,
      selectionBehavior,
      sortFieldValueMapper,
      sortingOrder,
      trackBorderColor,
      trackBorderWidth,
      trackColor,
      trackOpacity,
      useSeriesColor,
      xValueMapper,
      yValueMapper,
    ];
    return Object.hashAll(values);
  }
}
